package com.autodesk.akn.emr.web.controller;

import com.autodesk.akn.emr.dao.EMRDaoImpl;
import com.autodesk.akn.emr.dao.S3DaoImpl;
import com.autodesk.akn.emr.service.FileConverterService;
import com.autodesk.akn.emr.web.entity.SPSSConversionParams;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

public class SPSSConverterController extends MultiActionController {

    private EMRDaoImpl emrDAO;
    private S3DaoImpl s3DAO;
    private FileConverterService fileConverterService;

	public EMRDaoImpl getEmrDAO() {
		return emrDAO;
	}

	public void setEmrDAO(EMRDaoImpl emrDAO) {
		this.emrDAO = emrDAO;
	}

    public S3DaoImpl getS3DAO() {
        return s3DAO;
    }

    public void setS3DAO(S3DaoImpl s3DAO) {
        this.s3DAO = s3DAO;
    }


    public FileConverterService getFileConverterService() {
        return fileConverterService;
    }

    public void setFileConverterService(FileConverterService fileConverterService) {
        this.fileConverterService = fileConverterService;
    }


    /**
     *
     * @param hsr
     * E.G.:
     * inputBucket - globant-emr
     * inputKey - /
     * outputBucket - globant-emr
     * outputKey - /
     * conversionScope - isFolder
     * conversionType - headersOnly
     * @param hsr1
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "spssconverter/convert", method = RequestMethod.POST)
    public @ResponseBody String convert(HttpServletRequest hsr, HttpServletResponse hsr1) throws Exception {
        SPSSConversionParams params = new SPSSConversionParams();
        params.setInputBucket(hsr.getParameter("inputBucket"));
        params.setInputKey(hsr.getParameter("inputKey").substring(1));
        params.setOutputBucket(hsr.getParameter("outputBucket"));
        params.setFolder(hsr.getParameter("conversionScope"));
        if(params.getFolder().equals("isfolder")){
            params.setOutputKey(hsr.getParameter("outputKey").substring(1));
        }else{
            //For now, when we are processing a single .sav file, we replace the output file extension to csv.
            //In the future the extension and the file name can be parametrized
            params.setOutputKey(hsr.getParameter("outputKey").substring(1).replace(".sav", ".csv"));
        }
        params.setHeadersOnly(hsr.getParameter("conversionType"));

        String files = hsr.getParameter("files");
        List <String> filesToProcess = null;
        if(files!=null && !files.isEmpty()){
            filesToProcess= Arrays.asList(files.split("\\|"));
        } else {
            filesToProcess = s3DAO.listSavFiles(params.getInputBucket(), params.getInputKey());
        }
        boolean converted = fileConverterService.convertFromSav2Csv(params,filesToProcess);
        return String.valueOf(converted);
    }

    /**
     *
     * @param hsr
     * E.G.:
     * inputBucket - globant-emr
     * inputKey - /
     * outputBucket - globant-emr
     * outputKey - /
     * conversionScope - isFolder
     * conversionType - headersOnly
     * @param hsr1
     * @return
     * @throws Exception
     */

    /*
    @RequestMapping(value = "spssconverter/preprocess", method = RequestMethod.POST)
    public @ResponseBody String preprocessFiles(HttpServletRequest hsr, HttpServletResponse hsr1) throws Exception {
        SPSSConversionParams params = new SPSSConversionParams();
        params.setInputBucket(hsr.getParameter("inputBucket"));
        params.setInputKey(hsr.getParameter("inputKey").substring(1));
        params.setOutputBucket(hsr.getParameter("outputBucket"));
        params.setFolder(hsr.getParameter("conversionScope"));
        if(params.getFolder().equals("isfolder")){
            params.setOutputKey(hsr.getParameter("outputKey").substring(1));
        }else{
            //For now, when we are processing a single .sav file, we replace the output file extension to csv.
            //In the future the extension and the file name can be parametrized
            params.setOutputKey(hsr.getParameter("outputKey").substring(1).replace(".sav", ".csv"));
        }
        params.setHeadersOnly(hsr.getParameter("conversionType"));
    */
        /*
          Check the files parameter. If it contains some data, parse it and add the values to the
          filesToProcess list. Otherwise go to Amazon S3 and find the files for a specific bucket and prefix
        */
      /*
        String files = hsr.getParameter("files");
        List <String> filesToProcess = null;
        if(files!=null && !files.isEmpty()){
            filesToProcess= Arrays.asList(files.split("\\|"));
        } else {
            filesToProcess = s3DAO.listSavFiles(params.getInputBucket(), params.getInputKey());
        }

        if(filesToProcess == null || filesToProcess.isEmpty()){
            return "inputerror";
        }

        //Check if the files were already processed
        checkElementsAlreadyProcessed(params, filesToProcess);

        boolean converted = true;
        if(!filesToProcess.isEmpty()){
            //Launch SPSS file conversion
            converted = fileConversion(params, filesToProcess);
        }
        return String.valueOf(converted);
    }

    */
/*
    private boolean fileConversion(SPSSConversionParams params, List<String> filesToProcess) {
        List<String>filesToConvert =  this.checkElementsAlreadyConverted(params,filesToProcess);
        //Launch SPSS file conversion
        boolean converted = fileConverterService.convertFromSav2Csv(params,filesToConvert);

        if(converted){
            String jobId = String.valueOf(new Date().getTime());
            //Check if we're in a folder
            if(params.getFolder().equals("isfolder")){
                //iterate over each .sav file and store it
                if(filesToProcess!=null && !filesToProcess.isEmpty()){
                    String inputKey = params.getInputKey();
                    String outputKey = params.getOutputKey();
                    for(String file : filesToProcess){
                        params.setInputKey(inputKey+file);
                        params.setOutputKey(outputKey+file.replace(".sav", ".csv"));
                        saveSAVFile(params,jobId);
                    }
                }
            }else{
                params.setInputKey(params.getInputKey());
                params.setOutputKey(params.getOutputKey());
                saveSAVFile(params,jobId);
            }
            //Get all the savs for this job and process the questions of each sav file.
            List<Sav>savsToProcess = savDAO.getAllSavByJobFlowId(jobId);
            if(savsToProcess!=null && !savsToProcess.isEmpty()){
                questionProcessor.processQuestions(savsToProcess);
            }
        }
        return converted;
    }


    private void checkElementsAlreadyProcessed(SPSSConversionParams params, List<String> filesToProcess) {
        Iterator<String> i = filesToProcess.iterator();
        while (i.hasNext()){
            String filename = i.next();
            List<Sav> result = savDAO.getAllSavByPrefix(params.getInputBucket(), params.getInputKey()+filename);
            if(!result.isEmpty()){
                i.remove();
            }
        }
    }

    private List<String> checkElementsAlreadyConverted(SPSSConversionParams params, List<String>filesToProcess){
        List<String> filesToConvert = new ArrayList<String>();

        List<String>csvFiles = s3DAO.listCsvFiles(params.getInputBucket(),params.getInputKey());
        for(String file:filesToProcess){
            String tmpfile = file.replace(".sav",".csv");
            if (!csvFiles.contains(tmpfile)){
                filesToConvert.add(file);
            }
        }
        return filesToConvert;
    }


    private void saveSAVFile(SPSSConversionParams params, String jobFlowId){
        Sav sav = new Sav();
        sav.setInputBucket(params.getInputBucket());
        sav.setInputKey(params.getInputKey());
        sav.setOutputBucket(params.getOutputBucket());
        sav.setOutputKey(params.getOutputKey());
        sav.setDate(new Date());
        sav.setHeaders(true);
        sav.setJobFlowId(jobFlowId);
        sav.setStatus(Sav.Status.pending.name());
        savDAO.create(sav);
    }
    */
}
